package cc.rengu.igas.cops.core.service.trans.unionpay;

import cc.rengu.igas.cops.common.enums.LimitAuthTypeEnum;
import cc.rengu.igas.cops.common.enums.RespCodeEnum;
import cc.rengu.igas.cops.facade.base.BaseResponse;
import cc.rengu.igas.cops.facade.bean.TxnLimitAuthInfo;
import cc.rengu.igas.cops.facade.request.BankC2bLimitUpdateRequest;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.*;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 被扫---设置设置
 * 手机银行【ESB】—>支付系统
 * <p>
 * BizStatus：
 * 00-查询成功
 * 99-未设置
 * git工具测试
 *
 * @author paykey
 * @version 1.0.0 创建时间：2020.07.08
 */
public class BankC2bLimitUpdateService extends BizBaseService implements TransCustomImpl {
    @Override
    protected Object beforeBizProcess() throws Exception {
        BankC2bLimitUpdateRequest bankC2bLimitUpdateRequest = new BankC2bLimitUpdateRequest();
        ConvertUtil.convertOutput(bankC2bLimitUpdateRequest);
        //非空数据校验
        if (bankC2bLimitUpdateRequest.getAuthList() != null) {
            for (TxnLimitAuthInfo authInfo : bankC2bLimitUpdateRequest.getAuthList()) {
                if ((!StringUtil.isEmptyOrNull(authInfo.getAuthType())
                        && !StringUtil.isEmptyOrNull(authInfo.getStartAmt())
                        && !StringUtil.isEmptyOrNull(authInfo.getEndAmt())
                        && !StringUtil.isEmptyOrNull(authInfo.getAuthSingleLimitMaxAmt()))
                        || (StringUtil.isEmptyOrNull(authInfo.getAuthType())
                        && StringUtil.isEmptyOrNull(authInfo.getStartAmt())
                        && StringUtil.isEmptyOrNull(authInfo.getEndAmt())
                        && StringUtil.isEmptyOrNull(authInfo.getAuthSingleLimitMaxAmt()))) {

                } else {
                    //数据格式不完整
                    throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
                }
            }
        }
        return bankC2bLimitUpdateRequest;
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {

        // 录入参数
        BankC2bLimitUpdateRequest bankC2bLimitUpdateRequest = (BankC2bLimitUpdateRequest) request;
        // 行号
        String instId = bankC2bLimitUpdateRequest.getHeader().getInstId();

        // 根据核心客户查询用户
        UserService userService = new UserServiceImpl();
        UserInfo userInfo = userService.getUserInfo(instId, bankC2bLimitUpdateRequest.getAccNo(), bankC2bLimitUpdateRequest.getHeader().getSession());
        if (userInfo == null || !userInfo.getUserStatus().equals("00")) {
            rglog.info("用户不存在,instId:<{}>,instId:<{}>,accoutNo:<{}>", instId, bankC2bLimitUpdateRequest.getAccNo());
            throw new BizException(RespCodeEnum.USER_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.USER_STATUS_ABNORMAL.getRespDesc());
        }

        String limitInst = instId + "|" + userInfo.getUserInst() + "|" + userInfo.getUserId();

        //查询行级限额设置，个人限额不能高于机构限额
        TransLimitInfo orgLimit = userService.getUserLimitCfgInfo(instId, AppParamConstant.DEFAULT_INSTID, AppParamConstant.DEFAULT_INSTID, bankC2bLimitUpdateRequest.getBsnCode());
        if (orgLimit == null) {
            rglog.error("行级<{}>限额<{}>设置不存在!", instId, bankC2bLimitUpdateRequest.getBsnCode());
            throw new BizException(RespCodeEnum.ORG_LIMIT_CFG_NOT_FOUND.getRespCode(), RespCodeEnum.ORG_LIMIT_CFG_NOT_FOUND.getRespDesc());
        }

        //限额金额校验未通过
        checkLimitAmt(orgLimit, bankC2bLimitUpdateRequest);

        boolean registerFlag = false;
        //个人限额数据
        TransLimitInfo userLimit = userService.getUserLimitCfgInfo(instId, userInfo.getUserId(), userInfo.getUserInst(), bankC2bLimitUpdateRequest.getBsnCode());
        TransLimitInfo insertLimitCfg = null;
        if (userLimit == null) {
            insertLimitCfg = new TransLimitInfo();
            insertLimitCfg.setInstId(instId);
            insertLimitCfg.setLimitType(bankC2bLimitUpdateRequest.getBsnCode());
            insertLimitCfg.setLimitInst(limitInst);
            insertLimitCfg.setLimitAcctType("*");

            //设置限额
            insertLimitCfg.setSingleLimitMinAmt("0");
            insertLimitCfg.setSingleLimitMaxAmt(bankC2bLimitUpdateRequest.getSingleLimitMaxAmt());
            insertLimitCfg.setDayLimitAmt(bankC2bLimitUpdateRequest.getDaylimitMaxAmt());

            //判断是否这是认证方式的金额
            //设置授权类型限额
            //设置授权类型限额
            insertLimitCfg.setAuthLimitAmt(
                    setAuthLimitAmt(orgLimit.getAuthLimitAmt(),
                            bankC2bLimitUpdateRequest.getAuthList()));
            //新建数据
            registerFlag = userService.registerUserLimitInfo(insertLimitCfg);
        } else {
            insertLimitCfg = userLimit;
            insertLimitCfg.setSingleLimitMinAmt("0");
            insertLimitCfg.setSingleLimitMaxAmt(bankC2bLimitUpdateRequest.getSingleLimitMaxAmt());
            insertLimitCfg.setDayLimitAmt(bankC2bLimitUpdateRequest.getDaylimitMaxAmt());
            //设置授权类型限额
            insertLimitCfg.setAuthLimitAmt(
                    setAuthLimitAmt(orgLimit.getAuthLimitAmt(),
                            bankC2bLimitUpdateRequest.getAuthList()));
            //更新数据
            registerFlag = userService.registerUserLimitInfo(insertLimitCfg);
        }

        //设置失败
        if (!registerFlag) {
            throw new BizException(RespCodeEnum.SET_LIMIT_AMT_ERROR.getRespCode(), RespCodeEnum.SET_LIMIT_AMT_ERROR.getRespDesc());
        }

        //查询个人日支付金额
        BaseResponse bankC2bLimitUpdateResponse = new BaseResponse();        // 返回
        BizResponse bizResponse = new BizResponse();
        bizResponse.setResult(bankC2bLimitUpdateResponse);// 返回结果
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {
        BaseResponse retResponse = (BaseResponse) response.getResult();
        ConvertUtil.convertInput(retResponse);
    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        return null;
    }

    /**
     * 检验限额金额设置，设置的金额不能超过机构设置金额
     *
     * @param orgCfg
     * @param userCfg
     */
    private void checkLimitAmt(TransLimitInfo orgCfg, BankC2bLimitUpdateRequest userCfg) throws BizException {
        //检验日累计
        if (!StringUtil.isEmptyOrNull(userCfg.getDaylimitMaxAmt())
                && AmountUtil.compare("0", userCfg.getDaylimitMaxAmt()) > 0) {
            rglog.error("日累计限额不能小于0，instId:<{}>, accNo:<{}>, bsnCode:<{}>, userDayLimitAmt:<{}>", orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), userCfg.getDaylimitMaxAmt());
            throw new BizException(RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespCode(), "单日" + RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespDesc());
        } else if (!StringUtil.isEmptyOrNull(userCfg.getDaylimitMaxAmt())
                && AmountUtil.compare(orgCfg.getDayLimitAmt(), userCfg.getDaylimitMaxAmt()) < 0) {
            //日累计限额超限
            rglog.error("日累计限额超限，instId:<{}>, accNo:<{}>, bsnCode:<{}>, orgDayLimitAmt:<{}>, userDayLimitAmt:<{}>", orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgCfg.getDayLimitAmt(), userCfg.getDaylimitMaxAmt());
            throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), "单日限额" + RespCodeEnum.OVER_LIMIT_AMT.getRespDesc());
        }
        //检测单笔限额
        if (!StringUtil.isEmptyOrNull(userCfg.getSingleLimitMaxAmt())
                && AmountUtil.compare("0", userCfg.getSingleLimitMaxAmt()) > 0) {
            //单笔限额小于0
            rglog.error("单笔限额不能小于0，instId:<{}>, accNo:<{}>, bsnCode:<{}>, userSingleLimitAmt:<{}>", orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), userCfg.getSingleLimitMaxAmt());
            throw new BizException(RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespCode(), "单笔" + RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespDesc());
        }
        //单笔限额超过机构限额
        else if (!StringUtil.isEmptyOrNull(userCfg.getSingleLimitMaxAmt())
                && AmountUtil.compare(orgCfg.getSingleLimitMaxAmt(), userCfg.getSingleLimitMaxAmt()) < 0) {
            rglog.error("单笔限额超限，instId:<{}>, accNo:<{}>, bsnCode:<{}>, orgSingleLimitAmt:<{}>, userSingleLimitAmt:<{}>", orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgCfg.getSingleLimitMaxAmt(), userCfg.getSingleLimitMaxAmt());
            throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), "单笔限额" + RespCodeEnum.OVER_LIMIT_AMT.getRespDesc());
        }
        //单笔限额超过单日限额
        else if (!StringUtil.isEmptyOrNull(userCfg.getSingleLimitMaxAmt())
                && AmountUtil.compare(userCfg.getDaylimitMaxAmt(), userCfg.getSingleLimitMaxAmt()) < 0) {
            //单笔限额超限
            rglog.error("单笔限额超限，instId:<{}>, accNo:<{}>, bsnCode:<{}>, orgSingleLimitAmt:<{}>, userSingleLimitAmt:<{}>", orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgCfg.getSingleLimitMaxAmt(), userCfg.getSingleLimitMaxAmt());
            throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), "单笔限额不能大于单日限额");
        }

        if (userCfg.getAuthList() != null && !userCfg.getAuthList().isEmpty()) {
            Map<String, String> authMaps = JSON.parseObject(orgCfg.getAuthLimitAmt(), Map.class);
            for (TxnLimitAuthInfo authInfo : userCfg.getAuthList()) {
                //机构限额
                String authAmts = authMaps.get(authInfo.getAuthType());
                //认证方式名称
                String authTypeName = LimitAuthTypeEnum.getLimitAcctTypeDesc(authInfo.getAuthType());

                if (StringUtil.isEmptyOrNull(authAmts)) {
                    rglog.error("机构认证方式限额未设置!instId:<{}>, authType:<{}>", orgCfg.getInstId(), authInfo.getAuthType());
                    throw new BizException(RespCodeEnum.ORG_LIMIT_CFG_NOT_FOUND.getRespCode(), RespCodeEnum.ORG_LIMIT_CFG_NOT_FOUND.getRespDesc());
                }
                //机构限额设置
                String[] orgAmts = authAmts.split("\\|");

                //认证方式日累计限额开始金额校验
                if (AmountUtil.compare("0", authInfo.getStartAmt()) > 0) {
                    //单笔限额超限
                    rglog.error("认证方式<{}>日累计限额开始金额不能小于0，instId:<{}>, accNo:<{}>, startAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getBsnCode(), authInfo.getStartAmt());
                    throw new BizException(RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespCode(), authTypeName + "单日" + RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespDesc());
                }
                //认证方式日累计限额结束金额超限
                if (AmountUtil.compare("0", authInfo.getEndAmt()) > 0) {
                    //认证方式 日累计限额小于0
                    rglog.error("认证方式<{}>日累计限额结束金额不能小于0，instId:<{}>, accNo:<{}>, endAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getBsnCode(), authInfo.getEndAmt());
                    throw new BizException(RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespCode(), authTypeName + "单日" + RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespDesc());
                }
                //单日限额超过机构单日
                else if (AmountUtil.compare(orgAmts[1], authInfo.getEndAmt()) < 0) {
                    //用户限额查过机构限额
                    rglog.error("认证方式<{}>日累计限额结束金额超限，instId:<{}>, accNo:<{}>, bsnCode:<{}>, orgSingleLimitAmt:<{}>, authUserDayLimitAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgAmts[1], authInfo.getEndAmt());
                    throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), authTypeName + "单日限额设置不能大于机构" + authTypeName + "单日限额");
                }
                //认证方式单日限额超过
                else if (AmountUtil.compare(userCfg.getDaylimitMaxAmt(), authInfo.getEndAmt()) < 0) {
                    //用户限额查过机构限额
                    rglog.error("认证方式<{}>日累计限额大于用户单日限额，instId:<{}>, accNo:<{}>, bsnCode:<{}>, userDayLimitAmt:<{}>, authUserDayLimitAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), userCfg.getDaylimitMaxAmt(), authInfo.getEndAmt());
                    throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), authTypeName + "单日限额设置不能大于单日限额");
                }

                //认证方式单笔限额超限
                if (AmountUtil.compare("0", authInfo.getAuthSingleLimitMaxAmt()) > 0) {
                    //认证方式单笔限额金额小于0
                    rglog.error("认证方式<{}>单笔限额结束金额不能小于0，instId:<{}>, accNo:<{}>, authSingleLimitMaxAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getBsnCode(), authInfo.getAuthSingleLimitMaxAmt());
                    throw new BizException(RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespCode(), authTypeName + "单笔" + RespCodeEnum.LIMIT_AMT_LT_ZERE.getRespDesc());
                }
                //认证单笔限额超过机构单笔限额设置
                else if (AmountUtil.compare(orgAmts[2], authInfo.getAuthSingleLimitMaxAmt()) < 0) {
                    rglog.error("认证方式<{}>单笔限额超限，instId:<{}>, accNo:<{}>, bsnCode:<{}>, orgSingleLimitAmt:<{}>, authUserSingleLimitAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgAmts[2], authInfo.getAuthSingleLimitMaxAmt());
                    throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), authTypeName + "单笔限额" + RespCodeEnum.OVER_LIMIT_AMT.getRespDesc());
                }
                //认证单笔限额超过机构日累计限额设置
                else if (AmountUtil.compare(orgAmts[1], authInfo.getAuthSingleLimitMaxAmt()) < 0) {
                    //用户单笔金额超过
                    rglog.error("认证方式<{}>单笔限额大于机构日累计限额，instId:<{}>, accNo:<{}>, bsnCode:<{}>, authOrgDayLimitAmt:<{}>, authUserSingleLimitAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), orgAmts[1], authInfo.getAuthSingleLimitMaxAmt());
                    throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), authTypeName + "单笔限额不能大于机构" + authTypeName + "单日限额");
                }
                //认证单笔限额超过用户单笔限额设置
                else if (AmountUtil.compare(userCfg.getSingleLimitMaxAmt(), authInfo.getAuthSingleLimitMaxAmt()) < 0) {
                    //用户单笔金额超过
                    rglog.error("认证方式<{}>单笔限额大于单笔限额，instId:<{}>, accNo:<{}>, bsnCode:<{}>, userSingleLimitAmt:<{}>, authUserSingleLimitAmt:<{}>", authInfo.getAuthType(), orgCfg.getInstId(), userCfg.getAccNo(), userCfg.getBsnCode(), userCfg.getSingleLimitMaxAmt(), authInfo.getAuthSingleLimitMaxAmt());
                    throw new BizException(RespCodeEnum.OVER_LIMIT_AMT.getRespCode(), authTypeName + "单笔限额不能大于单笔限额");
                }
            }
        }
    }

    /**
     * 设置认证类型限额
     * 保存用户设置的认证类型限额
     * 用户未设置的认证类型，默认使用机构限额
     *
     * @param orgAuthLimitAmt
     * @param authLimitList
     * @return
     */
    private String setAuthLimitAmt(String orgAuthLimitAmt, List<TxnLimitAuthInfo> authLimitList) {
        Map<String, String> authLimitMap = JSON.parseObject(orgAuthLimitAmt, Map.class);
        if (authLimitList != null && !authLimitList.isEmpty()) {
            for (TxnLimitAuthInfo authLimit : authLimitList) {
                String startAmt = StringUtil.isEmptyOrNull(authLimit.getStartAmt()) ? "0.00" : authLimit.getStartAmt();
                String endAmt = StringUtil.isEmptyOrNull(authLimit.getEndAmt()) ? "0.00" : authLimit.getEndAmt();
                String singleAmt = StringUtil.isEmptyOrNull(authLimit.getAuthSingleLimitMaxAmt()) ? "0.00" : authLimit.getAuthSingleLimitMaxAmt();
                authLimitMap.put(authLimit.getAuthType(), startAmt + "|" + endAmt + "|" + singleAmt);
            }
        }
        return JSON.toJSONString(formatStartAmt(authLimitMap));
    }

    /**
     * 将限额的起始金额设为上一种认证方式的结束金额
     *
     * @param limitMap
     */
    private Map<String, String> formatStartAmt(Map<String, String> limitMap) {
        Iterator<String> keys = limitMap.keySet().iterator();
        Map<String, String> result = new HashMap<>();
        String sartAmt = "0.00";
        while (keys.hasNext()) {
            String key = keys.next();
            String[] values = limitMap.get(key).split("\\|");
            result.put(key, sartAmt + "|" + values[1] + "|" + values[2]);
            sartAmt = values[1];
        }
        return result;
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
